fix(streaming): reject Fin with out-of-range sequence instead of overflowing#145
Open
Jr-kenny wants to merge 1 commit into
Open
fix(streaming): reject Fin with out-of-range sequence instead of overflowing#145Jr-kenny wants to merge 1 commit into
Jr-kenny wants to merge 1 commit into
Conversation
…flowing A Fin proposal-part carries a peer-controlled sequence, and StreamState::insert turned it straight into expected_messages with `msg.sequence as usize + 1`. The comment there claimed that could not overflow because of MAX_MESSAGES_PER_STREAM, but expected_messages comes from the Fin sequence, not the message cap, so a Fin at u64::MAX overflowed and panicked in debug builds (and wedged the stream in release until the age sweep). A complete stream can never hold more than MAX_MESSAGES_PER_STREAM messages, so a Fin whose sequence is >= MAX_MESSAGES_PER_STREAM describes a stream that can never complete. Reject and evict it up front like the other malformed-stream paths, which also removes the overflow. Corrects the misleading comment and adds a regression test for the u64::MAX and boundary cases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #144.
What's going on
StreamState::insertincrates/malachite-app/src/streaming.rsworks out how many parts a stream should have from theFinmessage's sequence:The comment above it says the
+ 1can't overflow because ofMAX_MESSAGES_PER_STREAM, butexpected_messagesis taken from the Fin sequence, which is a wire field the sending peer controls, not from the message cap. A single gossipedFinatsequence = u64::MAXreaches that line unchecked (received_proposal_part.rs:163hands the raw message straight tostreams_map.insert), andu64::MAX as usize + 1overflows: a panic in debug or debug-assertions builds, and in release it wraps instead, so the stream can never complete and just sits on a per-peer slot until the 60s age sweep clears it.Fix
A complete stream holds
fin.sequence + 1messages and can never hold more thanMAX_MESSAGES_PER_STREAM, so aFinwithsequence >= MAX_MESSAGES_PER_STREAMis describing a stream that can never complete. I reject and evict it up front, the same way the other malformed-stream paths already do (newStreamInsertResult::FinSequenceOutOfRange), which also takes the overflow off the table. The misleading comment is corrected while I'm there.Testing
Added
test_fin_with_out_of_range_sequence_is_rejected_without_overflow, covering theu64::MAXcase and theMAX_MESSAGES_PER_STREAMboundary. Both now returnPendingwith no stream left tracked, instead of panicking. The rest of the streaming suite stays green:cargo clippy -p arc-node-consensus --libis clean too.